home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ccdl151s.zip / SOURCE / ARGS.C < prev    next >
C/C++ Source or Header  |  1997-03-15  |  5KB  |  179 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include "cmdline.h"
  25. /*
  26.  * This module handles command line arguments.  The main program defines
  27.  * an array specifying what arguments are allowed and what the activity
  28.  * should be for each argument and then calls parse_args giving it
  29.  * argv and argc as arguments.  Parse-args dispatches any arguments it
  30.  * finds to the action routine and then deletes the argument it found
  31.  * from argv[]
  32.  */
  33. /*
  34.  * The main program must define this array.  It customizes the types of
  35.  * arguments that will be allowed
  36.  *
  37.  */
  38. extern ARGLIST ArgList[];
  39.  
  40. static BOOL use_case;    /* Gets set for case sensitivity */
  41.  
  42. /* 
  43.  * Function that unlinks the argument from che argv[] chain
  44.  */
  45. static void remove_arg(int pos, int *count, char *list[])
  46. {
  47.   int i;
  48.  
  49.   /* Decrement length of list */
  50.   (*count)--;
  51.  
  52.   /* move items down */
  53.   for (i=pos; i<*count; i++)
  54.     list[i] = list[i+1];
  55.  
  56. }
  57. /*
  58.  * ompare two characters, ignoring case if necessary
  59.  */
  60. static BOOL cmatch(char t1, char t2)
  61. {
  62.   if (use_case)
  63.     return(t1 == t2);
  64.  
  65.   return(toupper(t1) == toupper(t2));
  66. }
  67. /* Routine scans a string to see if any of the characters match
  68.  *  the arguments, then dispatches to the action routine if so.
  69.  */
  70. /* Callbacks of the form
  71.  *   void boolcallback( char selectchar, BOOL value)
  72.  *   void switchcallback( char selectchar, BOOL value)  ;; value always true
  73.  *   void stringcallback( char selectchar, char *string)
  74.  */
  75. static int scan_args(char *string, int index, char *arg)
  76. {
  77.   int i=-1;
  78.   while (ArgList[++i].id) {
  79.     switch( ArgList[i].mode) {
  80.             case ARG_SWITCHSTRING:
  81.               if (cmatch(string[index], ArgList[i].id)) {
  82.         (* ArgList[i].routine)(string[index],&string[index]);
  83.          return (ARG_NEXTCHAR);
  84.           }
  85.           break;
  86.       case ARG_SWITCH:
  87.               if (cmatch(string[index], ArgList[i].id)) {
  88.         (* ArgList[i].routine)(string[index],(char *)TRUE);
  89.          return (ARG_NEXTCHAR);
  90.           }
  91.           break;
  92.       case ARG_BOOL:
  93.           if (cmatch(string[index], ArgList[i].id)) {
  94.         if (string[0] == ARG_SEPTRUE)
  95.           (* ArgList[i].routine)(string[index],(char *)TRUE);
  96.         else
  97.           (* ArgList[i].routine)(string[index],(char *)FALSE);
  98.         return(ARG_NEXTCHAR);
  99.           }
  100.           break;
  101.       case ARG_CONCATSTRING:
  102.           if (cmatch(string[index], ArgList[i].id)) {
  103.         (* ArgList[i].routine)(string[index], string+index+1);
  104.         return(ARG_NEXTARG);
  105.           }
  106.           break;
  107.       case ARG_NOCONCATSTRING:
  108.           if (cmatch(string[index], ArgList[i].id)) {
  109.         if (!arg)
  110.           return(ARG_NOARG);
  111.                 (* ArgList[i].routine)(string[index], arg);
  112.                 return(ARG_NEXTNOCAT);
  113.               }
  114.               break;
  115.     }
  116.   }
  117.   return(ARG_NOMATCH);
  118. }
  119. /*
  120.  * Main parse routine.  Scans for '-', then scan for arguments and
  121.  * delete from the argv[] array if so.
  122.  */
  123. BOOL parse_args(int *argc, char *argv[], BOOL case_sensitive)
  124. {
  125.   int pos = 0;
  126.  
  127.   BOOL retval = TRUE;
  128.   use_case = case_sensitive;
  129.  
  130.   while(++pos < *argc) {
  131.     if ((argv[pos][0] == ARG_SEPSWITCH) || (argv[pos][0] == ARG_SEPFALSE)
  132.           || (argv[pos][0] == ARG_SEPTRUE)) {
  133.       int argmode;
  134.       int index = 1;
  135.       int done = FALSE;
  136.       do {
  137.         /* Scan the present arg */
  138.         if (pos < *argc - 1)
  139.           argmode = scan_args(argv[pos], index, argv[pos+1]);
  140.         else
  141.           argmode = scan_args(argv[pos], index, 0);
  142.  
  143.         switch(argmode) {
  144.           case ARG_NEXTCHAR:
  145.                   /* If it was a char, go to the next one */
  146.                   if (!argv[pos][++index])
  147.                     done = TRUE;
  148.                   break;
  149.           case ARG_NEXTNOCAT:
  150.                   /* Otherwise if it was a nocat, remove the extra arg */
  151.                   remove_arg(pos, argc, argv);
  152.                   /* Fall through to NEXTARG */
  153.           case ARG_NEXTARG:
  154.                   /* Just a next arg, go do it */
  155.                   done = TRUE;
  156.                   break;
  157.           case ARG_NOMATCH:
  158.                   /* No such arg, spit an error  */
  159.                   fprintf(stderr,"Invalid Arg: %s\n", argv[pos]);
  160.                   done = TRUE;
  161.                   retval = FALSE;
  162.                   break;
  163.           case ARG_NOARG:
  164.                   /* Missing the arg for a CONCAT type, spit the error */
  165.                   fprintf(stderr,"Missing string for Arg %s\n", argv[pos]);
  166.                   done = TRUE;
  167.                   retval = FALSE;
  168.                   break;
  169.         };
  170.  
  171.       } while (!done);
  172.       /* We'll always get rid of the present arg
  173.        * And back up one
  174.              */
  175.       remove_arg(pos--, argc, argv);
  176.     }
  177.   }
  178.   return(retval);
  179. }